package com.example.mqtt.client;

import com.example.mqtt.tools.SlurryTools;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
@Slf4j
public class MqttClientConnect {

//    private static final String BROKER = "tcp://192.168.31.100:1883";
    private static final String BROKER = "tcp://101.132.242.94:1883";
    private static final String CLIENT_ID = "hitsoul_slurry";
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "Slurry123";


    private volatile static MqttClientConnect instance;
    private MqttClient client;

    private MqttClientConnect() {
        try {
            client = createMqttClient(BROKER, SlurryTools.getUUID());
            connectToBroker(client, USERNAME, PASSWORD);
        } catch (MqttException me) {
            handleMqttException(me);
        }
    }

    public static MqttClientConnect getInstance() {
        if (instance == null) {
            synchronized (MqttClientConnect.class) {
                if (instance == null) {
                    instance = new MqttClientConnect();
                }
            }
        }
        return instance;
    }

    public void sendMessage(String topic, String message) {
        if (client == null || !client.isConnected()) {
            log.info("Client is not connected.");
            return;
        }

        try {
            sendMqttMessage(client, topic, message);
        } catch (MqttException me) {
            handleMqttException(me);
        }
    }

    public void closeConnection() {
        if (client != null && client.isConnected()) {
            try {
                client.disconnect();
                client.close();
                log.info("Disconnected and closed");
            } catch (MqttException me) {
                handleMqttException(me);
            }
        } else {
            log.info("Client is not connected or already closed.");
        }
    }

    private MqttClient createMqttClient(String broker, String clientId) throws MqttException {
        return new MqttClient(broker, clientId, new MemoryPersistence());
    }

    private void connectToBroker(MqttClient client, String username, String password) throws MqttException {
        MqttConnectOptions connOpts = new MqttConnectOptions();
        connOpts.setUserName(username);
        connOpts.setPassword(password.toCharArray());
        connOpts.setCleanSession(true);

        log.info("Connecting to broker: " + BROKER);
        client.connect(connOpts);
        log.info("Connected");
    }

    private void sendMqttMessage(MqttClient client, String topic, String content) throws MqttException {
        log.info("Topic:::" + topic + "\r\n" + "Publishing message: " + content);

        MqttMessage message = new MqttMessage(content.getBytes());
        message.setQos(0); // 默认 QoS 为 2
        client.publish(topic, message);
        log.info("Message published");
    }

    private void handleMqttException(MqttException me) {
        log.info("reason " + me.getReasonCode());
        log.info("msg " + me.getMessage());
        log.info("loc " + me.getLocalizedMessage());
        log.info("cause " + me.getCause());
        log.info("excep " + me);
        me.printStackTrace();
    }

}
